//
//  MoApi.swift
//  molive
//
//  Created by zhu xietong on 2020/4/11.
//

import Foundation
import Alamofire


public enum MoResult<Value>{
    case success(Value,String)
    case error(String)
}

public class MoRequest {
    public enum Log {
        case request
        case all
        case response
    }
    public enum Status{
        case waiting
        case sending
        case success
        case error
        case cancel
    }
    
    public var id:String? = nil
    public var status = Status.waiting

    public var task = JoTask()
    public var requestID:String = ""
    public let uuid = UUID().uuidString
    public init(_ url:String? = nil) {
        if let url_ = url{
            task.url(url_)
        }
    }
}


public class MoApiManager{
    
    
    static var requests:[MoRequest] = []
    static func add(_ request:MoRequest){
        var have = false
        for r in MoApiManager.requests {
            if r.uuid == request.uuid{
                have = true
            }
        }
        if !have{
            requests.append(request)
        }
    }
    static func remove(_ request:MoRequest){
        var index:Int? = nil
        var i = 0
        for r in MoApiManager.requests {
            if r.uuid == request.uuid{
                index = i
            }
            i = i + 1
        }
        if let _index = index{
            requests.remove(at: _index)
        }
    }
}

public typealias MoJson = MoApi<NSMutableDictionary>

public class MoApi<Value>:MoRequest {
    
    public func cancel() {
        if status == .sending{
            task.cancel()
        }
    }
    
    
    public func log(_ log:Log)->MoApi<Value>{
        switch  log{
        case .all:
            task.log.log_response()
        case .request:
            task.log
        case .response:
            task.log_response()
        default:
            break
        }
        return self
    }
        
    public var get:MoApi<Value>{
        get{
            _ = task.get
            return self
        }
    }
    
    public var post:MoApi<Value>{
        get{
            _ = task.post
            return self
        }
    }
    
    public func send(){
        MoApiManager.add(self)
        status = .sending
        task.run()
    }
    @discardableResult
    public func id(_ id:String)->MoApi<Value>{
        self.id = id
        return self
    }
    
    @discardableResult
    public func url(_ url:String)->MoApi<Value>{
        _ = task.url(url)
        return self
    }
    
    @discardableResult
    public func parameters(_ parameters:[String:Any])->MoApi<Value>{
        task.params(parameters)
        return self
    }
    
    @discardableResult
    public func finish(_ callBack:@escaping (_:MoResult<Value>,_:MoRequest?)->Void)->MoApi<Value>{
        task.json_handle {[weak self] (status, msg, obj, resp) in
            if status.isSuccess{
                self?.status = .success
                if let value  = obj as? Value{
                    callBack(.success(value, msg),self)
                    if let ws = self{
                        MoApiManager.remove(ws)
                    }
                    return
                }
            }
         
            if let ws = self{
                MoApiManager.remove(ws)
                if ws.status == .cancel{
                    return
                }
            }
            self?.status = .error
            callBack(.error(msg),self)
        }
        return self
    }
    

}
